#include <modules\graphics\graphics_module.h>

namespace DelGE
{
	namespace Modules
	{
		namespace Graphics
		{
			GraphicsModule::GraphicsModule()
			{
				this->sName = "graphics";

				this->LoadModule();
			}

			GraphicsModule::~GraphicsModule()
			{
				this->UnloadModule();
			}

			void GraphicsModule::LoadModule()
			{
				this->pOpenGL_GraphicsInterface = new OpenGLGraphicsInterface();
			}

			void GraphicsModule::UnloadModule()
			{
				delete this->pOpenGL_GraphicsInterface;
			}

			OpenGLGraphicsInterface* GraphicsModule::GetInterface_OpenGL()
			{
				return this->pOpenGL_GraphicsInterface;
			}

			#if defined(DELGE_PLATFORM_WIN32)
			/*D3D9GraphicsInterface* GraphicsModule::GetInterface_D3D9()
			{
				return this->pD3D9_GraphicsInterface;
			}*/
			#endif

			void GraphicsModule::SetCurrentContext(GraphicsContext* pContext)
			{
				((GraphicsInterface*)this->pInterface)->SetCurrentContext(pContext);
			}

			GraphicsContext* GraphicsModule::GetCurrentContext()
			{
				return ((GraphicsInterface*)this->pInterface)->GetCurrentContext();
			}

			GraphicsContext* GraphicsModule::CreateContext(SystemGadget* pGadget)
			{
				return ((GraphicsInterface*)this->pInterface)->CreateContext(pGadget);
			}

			#if defined(DELGE_PLATFORM_WIN32)
			GraphicsContext* GraphicsModule::CreateContext(HWND hWnd)
			{
				return ((GraphicsInterface*)this->pInterface)->CreateContext(hWnd);
			}
			#endif

			void GraphicsModule::DestroyAllContexts()
			{
				((GraphicsInterface*)this->pInterface)->DestroyAllContexts();
			}

			void GraphicsModule::Setup2DProjection(int iWidth, int iHeight)
			{
				((GraphicsInterface*)this->pInterface)->Setup2DProjection(iWidth, iHeight);
			}

			void GraphicsModule::SetViewport(int iX, int iY, int iWidth, int iHeight)
			{
				((GraphicsInterface*)this->pInterface)->SetViewport(iX, iY, iWidth, iHeight);
			}

			void GraphicsModule::SetClearColor(int iRed, int iGreen, int iBlue, int iAlpha)
			{
				((GraphicsInterface*)this->pInterface)->SetClearColor(iRed, iGreen, iBlue, iAlpha);
			}

			void GraphicsModule::SetClearColor(const Color& rColor)
			{
				((GraphicsInterface*)this->pInterface)->SetClearColor(rColor);
			}
			
			int GraphicsModule::GetClearColor_Red()
			{
				return ((GraphicsInterface*)this->pInterface)->GetClearColor_Red();
			}

			int GraphicsModule::GetClearColor_Green()
			{
				return ((GraphicsInterface*)this->pInterface)->GetClearColor_Red();
			}

			int GraphicsModule::GetClearColor_Blue()
			{
				return ((GraphicsInterface*)this->pInterface)->GetClearColor_Red();
			}

			int GraphicsModule::GetClearColor_Alpha()
			{
				return ((GraphicsInterface*)this->pInterface)->GetClearColor_Red();
			}

			Color GraphicsModule::GetClearColor()
			{
				return ((GraphicsInterface*)this->pInterface)->GetClearColor();
			}

			void GraphicsModule::SetGlobalColor(int iRed, int iGreen, int iBlue, int iAlpha)
			{
				((GraphicsInterface*)this->pInterface)->SetGlobalColor(iRed, iGreen, iBlue, iAlpha);
			}

			void GraphicsModule::SetGlobalColor(const Color& rColor)
			{
				((GraphicsInterface*)this->pInterface)->SetGlobalColor(rColor);
			}
			
			int GraphicsModule::GetGlobalColor_Red()
			{
				return ((GraphicsInterface*)this->pInterface)->GetGlobalColor_Red();
			}

			int GraphicsModule::GetGlobalColor_Green()
			{
				return ((GraphicsInterface*)this->pInterface)->GetGlobalColor_Green();
			}

			int GraphicsModule::GetGlobalColor_Blue()
			{
				return ((GraphicsInterface*)this->pInterface)->GetGlobalColor_Blue();
			}

			int GraphicsModule::GetGlobalColor_Alpha()
			{
				return ((GraphicsInterface*)this->pInterface)->GetGlobalColor_Alpha();
			}

			Color GraphicsModule::GetGlobalColor()
			{
				return ((GraphicsInterface*)this->pInterface)->GetGlobalColor();
			}

			void GraphicsModule::ClearScreen()
			{
				((GraphicsInterface*)this->pInterface)->ClearScreen();
			}

			void GraphicsModule::Flip()
			{
				((GraphicsInterface*)this->pInterface)->Flip();
			}

			void GraphicsModule::SetVsync(bool bVsync)
			{
				((GraphicsInterface*)this->pInterface)->SetVsync(bVsync);
			}

			void GraphicsModule::SetBlendMode(DelGEGraphicsBlendMode eBlendMode)
			{
				((GraphicsInterface*)this->pInterface)->SetBlendMode(eBlendMode);
			}

			DelGEGraphicsBlendMode GraphicsModule::GetBlendMode()
			{
				return ((GraphicsInterface*)this->pInterface)->GetBlendMode();
			}

			Texture* GraphicsModule::LoadTexture(string sFilepath, 
										 const Color& oMaskColor, 
										 GraphicsTexture_UVWrapMode eUWrapMode,
										 GraphicsTexture_UVWrapMode eVWrapMode)
			{
				return ((GraphicsInterface*)this->pInterface)->LoadTexture(sFilepath, oMaskColor, eUWrapMode, eVWrapMode);
			}

			Texture* GraphicsModule::CreateTexture(int iWidth, int iHeight,
														   GraphicsTexture_UVWrapMode eUWrapMode,
														   GraphicsTexture_UVWrapMode eVWrapMode)
			{
				return ((GraphicsInterface*)this->pInterface)->CreateTexture(iWidth, iHeight, eUWrapMode, eVWrapMode);
			}

			void GraphicsModule::UnloadTexture(Texture* pGraphicsTexture)
			{
				delete pGraphicsTexture;
			}

			Font* GraphicsModule::LoadFont(string sFilepath, int iSize)
			{
				return ((GraphicsInterface*)this->pInterface)->LoadFont(sFilepath, iSize);
			}
			
			void GraphicsModule::UnloadFont(Font* pFont)
			{
				((GraphicsInterface*)this->pInterface)->UnloadFont(pFont);
			}

			void GraphicsModule::BeginRenderToTexture(Texture* pGraphicsTexture)
			{
				((GraphicsInterface*)this->pInterface)->BeginRenderToTexture(pGraphicsTexture);
			}

			void GraphicsModule::EndRenderToTexture()
			{
				((GraphicsInterface*)this->pInterface)->EndRenderToTexture();
			}

			void GraphicsModule::DrawRect(float fX, float fY, float fWidth, float fHeight)
			{
				((GraphicsInterface*)this->pInterface)->DrawRect(fX, fY, fWidth, fHeight);
			}

			void GraphicsModule::DrawLine(float fX0, float fY0, float fX1, float fY1)
			{
				((GraphicsInterface*)this->pInterface)->DrawLine(fX0, fY0, fX1, fY1);
			}

			void GraphicsModule::DrawTexture(Texture* pTexture, float fX, float fY, float fWidth, float fHeight)
			{
				((GraphicsInterface*)this->pInterface)->DrawTexture(pTexture, fX, fY, fWidth, fHeight);
			}

			void GraphicsModule::DrawTextureArea(Texture* pTexture, float fX, float fY, float fWidth, float fHeight,
												 int iAreaX, int iAreaY, int iAreaWidth, int iAreaHeight)
			{
				((GraphicsInterface*)this->pInterface)->DrawTextureArea(pTexture, fX, fY, fWidth, fHeight, iAreaX, iAreaY, iAreaWidth, iAreaHeight);
			}

			void GraphicsModule::DrawMesh(Mesh* pMesh, bool bAutoBuild)
			{
				((GraphicsInterface*)this->pInterface)->DrawMesh(pMesh, bAutoBuild);
			}

			void GraphicsModule::DrawModel(Model* pModel)
			{
				((GraphicsInterface*)this->pInterface)->DrawModel(pModel);
			}

			void GraphicsModule::DrawEntity(Entity* pEntity)
			{
				((GraphicsInterface*)this->pInterface)->DrawEntity(pEntity);
			}

			void GraphicsModule::DrawCamera(Camera* pCamera)
			{
				((GraphicsInterface*)this->pInterface)->DrawCamera(pCamera);
			}

			void GraphicsModule::DrawSprite(Sprite* pSprite)
			{
				((GraphicsInterface*)this->pInterface)->DrawSprite(pSprite);
			}

			void GraphicsModule::DrawText(string sText, float fX, float fY, Font* pFont)
			{
				((GraphicsInterface*)this->pInterface)->DrawTextA(sText, fX, fY, pFont);
			}

			float GraphicsModule::TextWidth(string sText, Font* pFont)
			{
				return ((GraphicsInterface*)this->pInterface)->TextWidth(sText, pFont);
			}

			float GraphicsModule::TextHeight(string sText, Font* pFont)
			{
				return ((GraphicsInterface*)this->pInterface)->TextHeight(sText, pFont);
			}

			void GraphicsModule::BindTexture(Texture* pTexture)
			{
				((GraphicsInterface*)this->pInterface)->BindTexture(pTexture);
			}

			void GraphicsModule::SetModelViewMatrix(const Matrix& rMatrix)
			{
				((GraphicsInterface*)this->pInterface)->SetModelViewMatrix(rMatrix);
			}

			void GraphicsModule::SetProjectionMatrix(const Matrix& rMatrix)
			{
				((GraphicsInterface*)this->pInterface)->SetProjectionMatrix(rMatrix);
			}

			Matrix GraphicsModule::GetModelViewMatrix()
			{
				return ((GraphicsInterface*)this->pInterface)->GetModelViewMatrix();
			}

			Matrix GraphicsModule::GetProjectionMatrix()
			{
				return ((GraphicsInterface*)this->pInterface)->GetProjectionMatrix();
			}

			void GraphicsModule::PushWorldMatrix()
			{
				((GraphicsInterface*)this->pInterface)->PushWorldMatrix();
			}

			void GraphicsModule::PopWorldMatrix()
			{
				((GraphicsInterface*)this->pInterface)->PopWorldMatrix();
			}

			void GraphicsModule::Begin2DRendering()
			{
				((GraphicsInterface*)this->pInterface)->Begin2DRendering();
			}

			void GraphicsModule::Begin3DRendering()
			{
				((GraphicsInterface*)this->pInterface)->Begin3DRendering();
			}

			void GraphicsModule::EnableWireframeMode()
			{
				((GraphicsInterface*)this->pInterface)->EnableWireframeMode();
			}

			void GraphicsModule::EnableDepthTesting()
			{
				((GraphicsInterface*)this->pInterface)->EnableDepthTesting();
			}

			void GraphicsModule::DisableWireframeMode()
			{
				((GraphicsInterface*)this->pInterface)->DisableWireframeMode();
			}

			void GraphicsModule::DisableDepthTesting()
			{
				((GraphicsInterface*)this->pInterface)->DisableDepthTesting();
			}

			void GraphicsModule::EnableLighting()
			{
				((GraphicsInterface*)this->pInterface)->EnableLighting();
			}

			void GraphicsModule::DisableLighting()
			{
				((GraphicsInterface*)this->pInterface)->DisableLighting();
			}
		}
	}
}
